package com.sunwayworld.basemodule.basedata.sampletype.service.impl;

import com.sunwayworld.basemodule.basedata.sampletype.bean.LimsSampleTypeBean;
import com.sunwayworld.basemodule.basedata.sampletype.service.LimsSampleTypeService;
import com.sunwayworld.basemodule.samplemanage.sample.bean.LimsSampleBean;
import com.sunwayworld.basemodule.samplemanage.sample.service.LimsSampleService;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.i18n.I18nHelper;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.sunwayworld.framework.spring.annotation.GikamBean;

import com.sunwayworld.basemodule.basedata.sampletype.dao.LimsSampleCategoryDao;
import com.sunwayworld.basemodule.basedata.sampletype.bean.LimsSampleCategoryBean;
import com.sunwayworld.basemodule.basedata.sampletype.service.LimsSampleCategoryService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;

import java.util.List;
import java.util.stream.Collectors;

@Repository
@GikamBean
public class LimsSampleCategoryServiceImpl implements LimsSampleCategoryService {

    @Autowired
    private LimsSampleCategoryDao limsSampleCategoryDao;
    
    @Autowired
    @Lazy
    private LimsSampleTypeService sampleTypeService;
    
    @Autowired
    @Lazy
    private LimsSampleService sampleService;

    @Override
    public LimsSampleCategoryDao getDao() {
        return limsSampleCategoryDao;
    }

    @Override
    @Transactional
    public Long insert(RestJsonWrapperBean jsonWrapper) {
        LimsSampleCategoryBean sampleCategory = jsonWrapper.parseUnique(LimsSampleCategoryBean.class);
        sampleCategory.setId(ApplicationContextHelper.getNextIdentity());
        getDao().insert(sampleCategory);
        return sampleCategory.getId();
    }

    @Override
    @Transactional
    public void delete(RestJsonWrapperBean wrapper) {
        List<LimsSampleCategoryBean> sampleCategoryBeans = wrapper.parse(LimsSampleCategoryBean.class);
        List<Long> sampleCategoryIds = sampleCategoryBeans.stream().map(LimsSampleCategoryBean::getId).collect(Collectors.toList());
        List<LimsSampleCategoryBean> categoryBeans = getDao().selectListByIds(sampleCategoryIds);
        if (categoryBeans.isEmpty()) return;
        List<LimsSampleTypeBean> sampleTypeBeans = sampleTypeService.selectListByFilter(SearchFilter.instance().match("sampleCategoryId", sampleCategoryIds).filter(MatchPattern.OR));
        // 校验样本类别下是否有被引用的样本类型
        if (!sampleTypeBeans.isEmpty()){
            List<String> sampleTypeCodes = sampleTypeBeans.stream().map(LimsSampleTypeBean::getSampleTypeCode).collect(Collectors.toList());
            List<LimsSampleBean> sampleBeans = sampleService.selectListByFilter(SearchFilter.instance().match("sampleTypeCode", sampleTypeCodes).filter(MatchPattern.OR));
            if (!sampleBeans.isEmpty()){
                List<String> usedTypeCodes = sampleBeans.stream().map(LimsSampleBean::getSampleTypeCode).distinct().collect(Collectors.toList());
                List<Long> usedCategoryIds = sampleTypeBeans.stream().filter(st -> usedTypeCodes.contains(st.getSampleTypeCode())).map(LimsSampleTypeBean::getSampleCategoryId).distinct().collect(Collectors.toList());
                String msg = categoryBeans.stream().filter(cb -> usedCategoryIds.contains(cb.getId())).map(LimsSampleCategoryBean::getSampleCategoryCode).collect(Collectors.joining(","));
                throw new InvalidDataException(I18nHelper.getMessage("EXCEPTION.TIP.SAMPLE.CATEGORY.DELETE").concat("【").concat(msg).concat("】").concat(I18nHelper.getMessage("EXCEPTION.TIP.FORBIDDEN.DELETE")));
            }
            sampleTypeService.getDao().deleteBy(sampleTypeBeans);
        }
        getDao().deleteByIdList(sampleCategoryIds);
    }
}
